package com.xbongbong.paas.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xbongbong.paas.pojo.dto.ApprovalRecordsDTO;
import com.xbongbong.paas.pojo.dto.DetailTabConditionListDTO;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.pojo.dto.FormDataGetDTO;
import com.xbongbong.paas.pojo.vo.ApprovalRecordsVO;
import com.xbongbong.paas.pojo.vo.FormDataAddGetVO;
import com.xbongbong.paas.pojo.vo.FormDataAddVO;
import com.xbongbong.paas.pojo.vo.FormDataUpdateGetVO;
import com.xbongbong.paas.pojo.vo.FormDataUpdateVO;
import com.xbongbong.paas.pojo.vo.ScreenListVO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.thread.TransmittableThreadLocalUtil;
import com.xbongbong.paas.toolbox.wrap.BaseVO;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.pro.businesstage.pojo.vo.ChangeClueStatusVO;
import com.xbongbong.pro.businesstage.pojo.vo.StageLogListVO;
import com.xbongbong.pro.cabinetfile.pojo.dto.CabinetFileListGetDTO;
import com.xbongbong.pro.clue.pojo.dto.ChangeClueStatusDTO;
import com.xbongbong.pro.constant.XbbProConstant;
import com.xbongbong.pro.customercommunicate.pojo.dto.CustomerDynamicListDTO;
import com.xbongbong.pro.customercommunicate.pojo.dto.DynamicListDTO;
import com.xbongbong.pro.customercommunicate.pojo.vo.CommunicateDynamicsListVO;
import com.xbongbong.pro.detailtab.dto.ChangeDocumentStatusSaveDTO;
import com.xbongbong.pro.detailtab.dto.ClueConvertSaveDTO;
import com.xbongbong.pro.detailtab.dto.ClueConvertSaveVO;
import com.xbongbong.pro.detailtab.dto.CustomerExpressSaveDTO;
import com.xbongbong.pro.detailtab.dto.CustomerExpressSetDTO;
import com.xbongbong.pro.detailtab.dto.CustomerInvoiceAddGetDTO;
import com.xbongbong.pro.detailtab.dto.CustomerInvoiceSaveDTO;
import com.xbongbong.pro.detailtab.dto.CustomerInvoiceSetDTO;
import com.xbongbong.pro.detailtab.dto.DelFromMyTeamDTO;
import com.xbongbong.pro.detailtab.dto.DelParentOrChildCustomerDTO;
import com.xbongbong.pro.detailtab.dto.DetailClueConvertDTO;
import com.xbongbong.pro.detailtab.dto.DetailCommunicateDTO;
import com.xbongbong.pro.detailtab.dto.DetailCopyDTO;
import com.xbongbong.pro.detailtab.dto.DetailTabDataGetDTO;
import com.xbongbong.pro.detailtab.dto.DetailTabSettingGetDTO;
import com.xbongbong.pro.detailtab.dto.DetailTabSettingSaveDTO;
import com.xbongbong.pro.detailtab.dto.DetailUpdateGetDTO;
import com.xbongbong.pro.detailtab.dto.DistributionPerformanceSaveDTO;
import com.xbongbong.pro.detailtab.dto.FinishPlanDTO;
import com.xbongbong.pro.detailtab.dto.LinkAddBeforeDTO;
import com.xbongbong.pro.detailtab.dto.LinkAddGetDTO;
import com.xbongbong.pro.detailtab.dto.ManagementSummaryDTO;
import com.xbongbong.pro.detailtab.dto.MarketActivityEffectGetDTO;
import com.xbongbong.pro.detailtab.dto.MyTeamGetDTO;
import com.xbongbong.pro.detailtab.dto.PanoramaInitDTO;
import com.xbongbong.pro.detailtab.dto.PrintDataVisibleDTO;
import com.xbongbong.pro.detailtab.dto.SetChildCustomerDTO;
import com.xbongbong.pro.detailtab.dto.SetDefaultBomVersionDTO;
import com.xbongbong.pro.detailtab.dto.SetMainContactDTO;
import com.xbongbong.pro.detailtab.dto.SetParentCustomerDTO;
import com.xbongbong.pro.detailtab.dto.SupplierProductAddDTO;
import com.xbongbong.pro.detailtab.dto.SupplierProductDelDTO;
import com.xbongbong.pro.detailtab.dto.UpdateMyTeamDTO;
import com.xbongbong.pro.detailtab.vo.ChangeDocumentStatusSaveVO;
import com.xbongbong.pro.detailtab.vo.CustomerInvoiceAddGetVO;
import com.xbongbong.pro.detailtab.vo.DetailCommunicateVO;
import com.xbongbong.pro.detailtab.vo.DetailTabGetVO;
import com.xbongbong.pro.detailtab.vo.DetailTabLinkAddBeforeVO;
import com.xbongbong.pro.detailtab.vo.DetailTabSettingGetVO;
import com.xbongbong.pro.detailtab.vo.DistributionPerformanceGetVO;
import com.xbongbong.pro.detailtab.vo.ExpenseSummaryVO;
import com.xbongbong.pro.detailtab.vo.HistoryStageVO;
import com.xbongbong.pro.detailtab.vo.InvoiceExpressGetVO;
import com.xbongbong.pro.detailtab.vo.ManagementSummaryVO;
import com.xbongbong.pro.detailtab.vo.MarketActivityEffectGetVO;
import com.xbongbong.pro.detailtab.vo.MyTeamGetVO;
import com.xbongbong.pro.detailtab.vo.PanoramaInitVO;
import com.xbongbong.pro.detailtab.vo.ProductDetailVO;
import com.xbongbong.pro.detailtab.vo.ProductSummaryVO;
import com.xbongbong.pro.detailtab.vo.ProductUserVO;
import com.xbongbong.pro.detailtab.vo.QuotationTrendVO;
import com.xbongbong.pro.detailtab.vo.SupplierProductVO;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.fromdatadictionary.pojo.vo.DictionaryArrayVO;
import com.xbongbong.pro.listbatch.pojo.dto.ListBatchDTO;
import com.xbongbong.pro.marketManage.pojo.dto.RelationSaleClueListDTO;
import com.xbongbong.pro.marketManage.pojo.vo.RelationSaleClueListVO;
import com.xbongbong.pro.outstock.pojo.dto.OutstockShippingDTO;
import com.xbongbong.pro.outstock.pojo.vo.OutstockShippingVO;
import com.xbongbong.pro.payment.pojo.vo.PaymentVO;
import com.xbongbong.pro.payplan.pojo.dto.PayPlanBadReturnDTO;
import com.xbongbong.pro.payplan.pojo.vo.PayPlanVO;
import com.xbongbong.pro.product.pojo.vo.ProductSearchVO;
import com.xbongbong.pro.product.pojo.vo.RelationProductListVO;
import com.xbongbong.pro.quatation.pojo.dto.QuotationHistoryDTO;
import com.xbongbong.pro.quatation.pojo.dto.QuotationProductSearchDTO;
import com.xbongbong.pro.quatation.pojo.dto.QuotationTrendDTO;
import com.xbongbong.pro.webdetail.pojo.dto.PaymentReturnDTO;
import com.xbongbong.pro.weblist.pojo.dto.SaasBaseDTO;
import com.xbongbong.pro.workorder.pojo.dto.WorkOrderRelationTabGetDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.service.BusinessExpenseService;
import com.xbongbong.saas.service.BusinessProductService;
import com.xbongbong.saas.service.ClueService;
import com.xbongbong.saas.service.MarketActivityEffectService;
import com.xbongbong.saas.service.PayPlanService;
import com.xbongbong.saas.service.PaymentService;
import com.xbongbong.saas.service.QuotationService;
import com.xbongbong.saas.service.SaasDetailTabService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Objects;

/**
 * 详情页Tab栏接口
 *
 * @author feng.zheng
 * @version v1.0
 * @date 2019/1/15 15:42
 * @since v1.0
 */
@RestController
@RequestMapping(value = XbbProConstant.API_ROOT_PREFIX + "/detail/tab")
public class SaasDetailTabController {

    private static final Logger LOG = LoggerFactory.getLogger(SaasDetailTabController.class);

    @Resource
    private SaasDetailTabService saasDetailTabService;
    @Resource
    private MarketActivityEffectService marketActivityEffectService;
    @Resource
    private BusinessProductService businessProductService;
    @Resource
    private PaymentService paymentService;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private QuotationService quotationService;
    @Resource
    private PayPlanService payPlanService;
    @Resource
    private BusinessExpenseService businessExpenseService;
    @Resource
    private ClueService clueService;


    @RequestMapping(value = "/customerContact/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getCustomerContact(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getCustomerContact(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/supplierContact/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getSupplierContact(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getSupplierContact(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 获取供应商采购记录
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author chaoxiong.lei
     * @date 9:58 2019/3/27
     * @since v1.0
     **/
    @RequestMapping(value = "/supplier/purchaseList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String supplierPurchaseList(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.supplierPurchaseList(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 获取单据关联入库记录
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author chaoxiong.lei
     * @date 9:58 2019/3/27
     * @since v1.0
     **/
    @RequestMapping(value = "/instock/relationalList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String relationalInstockList(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.relationalInstockList(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 获取单据关联出库记录
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author chaoxiong.lei
     * @date 9:58 2019/3/27
     * @since v1.0
     **/
    @RequestMapping(value = "/outstock/relationalList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String relationalOutstockList(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.relationalOutstockList(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/parentAndChildCustomer/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getParentAndChildCustomer(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO parentAndChildCustomerGetVO = saasDetailTabService.getParentAndChildCustomer(detailTabDataGetDTO);
                response = new XbbResponse<>(parentAndChildCustomerGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/mainContact/set", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String setMainContact(@RequestBody @Valid SetMainContactDTO setMainContactDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                // 判断是否跳过重复提交校验
                if (!Boolean.TRUE.equals(setMainContactDTO.getIgnoreConCheck())) {
                    //重复提交校验
                    if (!paasRedisHelper.checkConcurrentLock(setMainContactDTO)) {
                        response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                        return JSON.toJSONString(response);
                    }
                }
                BaseVO baseVO = saasDetailTabService.setMainContact(setMainContactDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/customerOpportunity/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getCustomerOpportunity(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getCustomerOpportunity(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }


    @RequestMapping(value = "/customerContract/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getCustomerContract(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getCustomerContract(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * Description:工单记录
     * @param workOrderRelationTabGetDTO
     * @author 刘阳
     * @date 2019/5/14 10:32 AM
     * @since v1.0
     */
    @RequestMapping(value = "/workOrderContract/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getWorkOrderContract(@RequestBody @Valid WorkOrderRelationTabGetDTO workOrderRelationTabGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getWorkOrderContractWeb(workOrderRelationTabGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * Description: 报价单
     * @param detailTabDataGetDTO
     * @param br
     * @return java.lang.String
     * @author 刘阳
     * @date 2019/8/28 2:21 PM
     * @since v1.0
     */
    @RequestMapping(value = "/quotationTabData/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getQuotationContract(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getQuotationTabData(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/customer/quotation/product", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String customerQuotationProduct(@RequestBody @Valid QuotationProductSearchDTO quotationProductSearchDTO, BindingResult br) {
        XbbResponse<ProductSearchVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ProductSearchVO productSearchVO = saasDetailTabService.customerQuotationProduct(quotationProductSearchDTO);
                response = new XbbResponse<>(productSearchVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/customer/quotation/trend", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String customerQuotationTrend(@RequestBody @Valid QuotationTrendDTO quotationTrendDTO, BindingResult br) {
        XbbResponse<QuotationTrendVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                QuotationTrendVO quotationTrendVO = saasDetailTabService.quotationTrend(quotationTrendDTO);
                response = new XbbResponse<>(quotationTrendVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * Description: 历史版本
     * @param quotationHistoryDTO
     * @param br
     * @author 刘阳
     * @date 2019/8/14 7:31 PM
     * @since v1.0
     */
    @RequestMapping(value = "/quotationHistory", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getHistory(@RequestBody @Valid QuotationHistoryDTO quotationHistoryDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = quotationService.getHistory(quotationHistoryDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/payment/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getPayment(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getPayment(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/myTeam/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getMyTeam(@RequestBody @Valid MyTeamGetDTO myTeamGetDTO, BindingResult br) {
        XbbResponse<MyTeamGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                MyTeamGetVO myTeamGetVO = saasDetailTabService.getMyTeam(myTeamGetDTO);
                response = new XbbResponse<>(myTeamGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/updateMyTeam", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String updateMyTeam(@RequestBody @Valid UpdateMyTeamDTO updateMyTeamDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                // 判断是否跳过重复提交校验
                if (!Boolean.TRUE.equals(updateMyTeamDTO.getIgnoreConCheck())) {
                    //重复提交校验
                    if (!paasRedisHelper.checkConcurrentLock(updateMyTeamDTO)) {
                        response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                        return JSON.toJSONString(response);
                    }
                }

                BaseVO baseVO = saasDetailTabService.updateMyTeam(updateMyTeamDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/delFromMyTeam", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String delFromMyTeam(@RequestBody @Valid DelFromMyTeamDTO delFromMyTeamDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                BaseVO baseVO = saasDetailTabService.delFromMyTeam(delFromMyTeamDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 获取销项发票开票历史
     * @param detailTabDataGetDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/invoiceHistory/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getInvoiceHistory(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getInvoiceHistory(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 获取进项发票开票历史
     * @param detailTabDataGetDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/purchaseInvoiceHistory/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getPurchaseInvoiceHistory(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getPurchaseInvoiceHistory(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/redInvoice/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getRedInvoice(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(detailTabDataGetDTO.getSaasMark(), detailTabDataGetDTO.getBusinessType(), null, detailTabDataGetDTO.getDistributorMark());
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getRedInvoice(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/paymentSheet/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getPaymentSheet(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getPaymentSheet(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 回款单详情-红冲记录
     * @param detailTabDataGetDTO
     * @param br
     * @return java.lang.String
     * @author zcp
     * @date 19/11/29 029 22:05
     * @update 19/11/29 029 22:05
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/redPaymentSheet/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getRedPaymentSheet(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getRedPaymentSheet(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 应收款详情-红冲记录
     * @param detailTabDataGetDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/redReceivables/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getRedReceivables(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getRedReceivables(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 付款单详情-红冲记录
     * @param detailTabDataGetDTO
     * @param br
     * @return java.lang.String
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/redPaySheet/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getRedPaySheet(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getRedPaySheet(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/paySheet/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getPaySheet(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                //这边记住需要用付款单的businessType,因为下面取的都是付款单列表
                TransmittableThreadLocalUtil.setValue(detailTabDataGetDTO.getSaasMark(), XbbRefTypeEnum.PAY_SHEET.getCode(), BasicConstant.ZERO_LONG, detailTabDataGetDTO.getDistributorMark());
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getPaySheet(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/payPlan/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getPayPlan(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getPayPlan(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/redOtherIncome/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getRedOtherIncome(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getRedOtherIncome(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/redOtherExpense/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getRedOtherExpense(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getRedOtherExpense(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/parentCustomer/set", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String setParentCustomer(@RequestBody @Valid SetParentCustomerDTO setParentCustomerDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                BaseVO baseVO = saasDetailTabService.setParentCustomer(setParentCustomerDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/childCustomer/set", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String setChildCustomer(@RequestBody @Valid SetChildCustomerDTO setChildCustomerDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                BaseVO baseVO = saasDetailTabService.setChildCustomer(setChildCustomerDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/parentOrChildCustomer/delete", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String delParentOrChildCustomer(@RequestBody @Valid DelParentOrChildCustomerDTO delParentOrChildCustomerDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                BaseVO baseVO = saasDetailTabService.delParentOrChildCustomer(delParentOrChildCustomerDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/customerInvoiceExpress/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getInvoiceAndExpress(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<InvoiceExpressGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                InvoiceExpressGetVO invoiceExpressGetVO = saasDetailTabService.getCustomerInvoiceExpress(detailTabDataGetDTO);
                response = new XbbResponse<>(invoiceExpressGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/customerInvoiceExplainAdd/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String customerInvoiceExplainAddGet(@RequestBody @Valid CustomerInvoiceAddGetDTO customerInvoiceAddGetDTO, BindingResult br) {
        XbbResponse<CustomerInvoiceAddGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                CustomerInvoiceAddGetVO customerInvoiceAddGetVO = saasDetailTabService.getCustomerInvoiceExplain(customerInvoiceAddGetDTO);
                response = new XbbResponse<>(customerInvoiceAddGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/customerInvoice/save", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String saveCustomerInvoice(@RequestBody @Valid CustomerInvoiceSaveDTO customerInvoiceSaveDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                BaseVO baseVO = saasDetailTabService.saveCustomerInvoice(customerInvoiceSaveDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/customerExpress/save", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String saveCustomerExpress(@RequestBody @Valid CustomerExpressSaveDTO customerExpressSaveDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                BaseVO baseVO = saasDetailTabService.saveCustomerExpress(customerExpressSaveDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/customerExpress/set", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String setCustomerExpress(@RequestBody @Valid CustomerExpressSetDTO customerExpressSetDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                BaseVO baseVO = saasDetailTabService.setCustomerExpress(customerExpressSetDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/customerInvoice/set", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String setCustomerInvoice(@RequestBody @Valid CustomerInvoiceSetDTO customerInvoiceSetDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                BaseVO baseVO = saasDetailTabService.setCustomerInvoice(customerInvoiceSetDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/product/getInstock", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getInstock(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getProductInstock(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 获取产品负责人/部门
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author chaoxiong.lei
     * @date 13:53 2019/3/27
     * @since v1.0
     **/
    @RequestMapping(value = "/product/getProductUserRelation", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getProductUserRelation(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<ProductUserVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ProductUserVO productUserVO = saasDetailTabService.getProductUserRelation(detailTabDataGetDTO);
                response = new XbbResponse<>(productUserVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 获取产品详情
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author chaoxiong.lei
     * @date 13:53 2019/3/27
     * @since v1.0
     **/
    @RequestMapping(value = "/product/detail", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String productDetail(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<ProductDetailVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ProductDetailVO productDetailVO = saasDetailTabService.productDetail(detailTabDataGetDTO);
                response = new XbbResponse<>(productDetailVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/product/getOutstock", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getOutstock(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getProductOutstock(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }
    /**
    * @Description:  产品详情页产品介绍tab接口
    * @Param: [detailTabDataGetDTO, br]
    * @return: java.lang.String
    * @Author: cyy
    * @Date: 2019/10/9
    */
    @RequestMapping(value = "/product/getInstruction", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getInstruction(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<ProductDetailVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ProductDetailVO productDetailVO = saasDetailTabService.getProductInstruction(detailTabDataGetDTO);
                response = new XbbResponse<>(productDetailVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }
    @RequestMapping(value = "/product/getChildProductList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getChildProductList(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getChildProductListAndSpec(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/product/getBatchList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getBatchList(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getChildProductBatchList(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/product/getPurchase", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getPurchase(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.PURCHASE.getCode(), null, DistributorMarkEnum.OTHER.getCode());
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getPurchaseList(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/product/getPurchaseReturned", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getPurchaseReturned(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getPurchaseReturnedList(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/product/getSupplier", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getSupplier(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(detailTabDataGetDTO.getSaasMark(), XbbRefTypeEnum.SUPPLIER.getCode(), null, detailTabDataGetDTO.getDistributorMark());
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getSupplierList(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/product/getGuaranteeInfo", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getGuaranteeInfo(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getGuaranteeInfo(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 产品详情页子产品库存信息
     *
     * @param detailTabDataGetDTO 入参
     * @param br                  错误结果
     * @author chaoxiong.lei
     * @date 11:04 2019/3/18
     * @since v1.0
     **/
    @RequestMapping(value = "/product/getChildProductStockAjax", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getChildProductStockAjax(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(detailTabDataGetDTO.getSaasMark(), detailTabDataGetDTO.getBusinessType(), null, detailTabDataGetDTO.getDistributorMark());
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getChildProductStock(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 产品详情获取产品关联的合同
     *
     * @param detailTabDataGetDTO 入参
     * @param br                  错误结果
     * @author chaoxiong.lei
     * @date 11:04 2019/3/18
     * @since v1.0
     **/
    @RequestMapping(value = "/product/getContract", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getContract(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(detailTabDataGetDTO.getSaasMark(), XbbRefTypeEnum.CONTRACT.getCode(), null, detailTabDataGetDTO.getDistributorMark());
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getRelativeContract(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 获取BOM结构
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author chaoxiong.lei
     * @date 11:04 2019/3/18
     * @since v1.0
     **/
    @RequestMapping(value = "/bomBill/getBomBillProductStructure", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getBomBillProductStructure(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getBomProductStructure(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 详情页获取关联产品信息
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author chaoxiong.lei
     * @date 11:04 2019/3/18
     * @since v1.0
     **/
//    @RequestMapping(value = "/productList/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
//    public String getProductList(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
//        XbbResponse<BusinessProductListVO> response;
//        if (br.hasErrors()) {
//            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
//            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
//        } else {
//            try {
//                BusinessProductListVO businessProductListVO = businessProductService.getBusinessProductList(detailTabDataGetDTO);
//                response = new XbbResponse<>(businessProductListVO);
//            } catch (XbbException e) {
//                response = new XbbResponse<>(e);
//            }
//        }
//        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
//    }

    /**
     * 详情页获取关联产品信息
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author chaoxiong.lei
     * @date 11:04 2019/3/18
     * @since v1.0
     **/
    @RequestMapping(value = "/relationProductList/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getRelationProductList(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<RelationProductListVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                RelationProductListVO relationProductListVO = businessProductService.getRelationProductList(detailTabDataGetDTO);
                response = new XbbResponse<>(relationProductListVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 详情页汇总关联产品信息
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author long.rao
     * @date 2019-08-28 10:16
     **/
    @RequestMapping(value = "/productList/summary", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String summaryProductList(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<ProductSummaryVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ProductSummaryVO productSummaryVO = businessProductService.summaryProductList(detailTabDataGetDTO);
                response = new XbbResponse<>(productSummaryVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/getBusinessStageArray", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getBusinessStageArray(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<StageLogListVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                StageLogListVO stageLogListVO = saasDetailTabService.getCustomerStageArray(detailTabDataGetDTO);
                response = new XbbResponse<>(stageLogListVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/getBusinessHistoryStage", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getBusinessHistoryStage(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<HistoryStageVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                HistoryStageVO historyStageVO = saasDetailTabService.getHistoryStage(detailTabDataGetDTO);
                response = new XbbResponse<>(historyStageVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/createContract", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String createContract(@RequestBody @Valid ListBatchDTO listBatchDTO, BindingResult br) {
        XbbResponse<FormDataAddGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                FormDataAddGetVO formDataAddGetVO = saasDetailTabService.createContract(listBatchDTO);
                response = new XbbResponse<>(formDataAddGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/purchaseOrder/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getContractPurchase(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getContractPurchase(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }


    @RequestMapping(value = "/linkAdd/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String linkAddGet(@RequestBody @Valid LinkAddGetDTO linkAddGetDTO, BindingResult br) {
        XbbResponse<FormDataAddGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(linkAddGetDTO.getSaasMark(), linkAddGetDTO.getLinkBusinessType(), null, linkAddGetDTO.getDistributorMark());
                FormDataAddGetVO formDataAddGetVO = saasDetailTabService.linkAddGet(linkAddGetDTO);
                response = new XbbResponse<>(formDataAddGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/clue/convert/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String clueConvertGet(@RequestBody @Valid DetailClueConvertDTO clueConvertDTO, BindingResult br) {
        XbbResponse<FormDataAddGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.CLUE.getCode(), null, clueConvertDTO.getDistributorMark());
                FormDataAddGetVO formDataAddGetVO = saasDetailTabService.clueConvertGet(clueConvertDTO);
                response = new XbbResponse<>(formDataAddGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/clue/convert/save", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String clueConvertSave(@RequestBody @Valid ClueConvertSaveDTO clueConvertDTO, BindingResult br) {
        XbbResponse<ClueConvertSaveVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ClueConvertSaveVO clueConvertSaveVO = saasDetailTabService.clueConvertSave(clueConvertDTO);
                response = new XbbResponse<>(clueConvertSaveVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/copy", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String copy(@RequestBody @Valid DetailCopyDTO detailCopyDTO, BindingResult br) {
        XbbResponse<FormDataUpdateGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                FormDataUpdateGetVO formDataUpdateGetVO = saasDetailTabService.copy(detailCopyDTO);
                response = new XbbResponse<>(formDataUpdateGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/defaultBomVersion/set", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String setDefaultBomVersion(@RequestBody @Valid SetDefaultBomVersionDTO setDefaultBomVersionDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.BOM_BILL.getCode(), null, setDefaultBomVersionDTO.getDistributorMark());
                BaseVO baseVO = saasDetailTabService.setDefaultBomVersion(setDefaultBomVersionDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 回款坏账还原
     * @param paymentReturnDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/badDebtReturn", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String badDebtReturn(@RequestBody @Valid PaymentReturnDTO paymentReturnDTO, BindingResult br) {
        XbbResponse<PaymentVO> response;
        if(br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                PaymentVO paymentVO = paymentService.badDebtReturn(paymentReturnDTO);
                response = new XbbResponse<>(paymentVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/payPlan/badDebtReturn", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String payPlanBadDebtReturn(@RequestBody @Valid PayPlanBadReturnDTO payPlanBadReturnDTO, BindingResult br) {
        XbbResponse<PayPlanVO> response;
        if(br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                PayPlanVO payPlanVO = payPlanService.badDebtReturn(payPlanBadReturnDTO);
                response = new XbbResponse<>(payPlanVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/detailUpdate/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String detailUpdateGet(@RequestBody @Valid DetailUpdateGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<FormDataUpdateGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                FormDataUpdateGetVO formDataUpdateGetVO = saasDetailTabService.detailUpdateGet(detailTabDataGetDTO);
                response = new XbbResponse<>(formDataUpdateGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/getWastageCase", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getWastageCase(@RequestBody @Valid SaasBaseDTO saasBaseDTO, BindingResult br) {
        XbbResponse<DictionaryArrayVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
//                stageWorkFinishDTO.setBusinessType(XbbRefTypeEnum.CUSTOMER_STAGE.getCode());
                DictionaryArrayVO dictionaryArrayVO = saasDetailTabService.getWastageCase(saasBaseDTO);
                response = new XbbResponse<>(dictionaryArrayVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/distributionPerformance/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getDistributionPerformance(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DistributionPerformanceGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DistributionPerformanceGetVO distributionPerformanceGetVO = saasDetailTabService.getDistributionPerformance(detailTabDataGetDTO);
                response = new XbbResponse<>(distributionPerformanceGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/distributionPerformance/save", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String saveDistributionPerformance(@RequestBody @Valid DistributionPerformanceSaveDTO distributionPerformanceSaveDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                // ----------------------------------repeat post----------------------------------------------
                // 判断是否跳过重复提交校验
                if (!Boolean.TRUE.equals(distributionPerformanceSaveDTO.getIgnoreConCheck())) {
                    //重复提交校验
                    if (!paasRedisHelper.checkConcurrentLock(distributionPerformanceSaveDTO)) {
                        response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                        return JSON.toJSONString(response);
                    }
                }
                // ----------------------------------repeat post----------------------------------------------

                BaseVO baseVO = saasDetailTabService.saveDistributionPerformance(distributionPerformanceSaveDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/detailCommunicate/save", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String saveCustomerCommunicate(@RequestBody @Valid FormDataAddDTO formDataAddDTO, BindingResult br) {
        XbbResponse<FormDataAddVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                // ----------------------------------repeat post----------------------------------------------
                // 判断是否跳过重复提交校验
                if (!Boolean.TRUE.equals(formDataAddDTO.getIgnoreConCheck())) {
                    //重复提交校验
                    if (!paasRedisHelper.checkConcurrentLock(formDataAddDTO)) {
                        response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                        return JSON.toJSONString(response);
                    }
                }
                // ----------------------------------repeat post----------------------------------------------

                TransmittableThreadLocalUtil.setValue(formDataAddDTO.getSaasMark(), formDataAddDTO.getBusinessType(), formDataAddDTO.getMenuId(), formDataAddDTO.getDistributorMark());
                FormDataAddVO formDataAddVO = saasDetailTabService.saveCustomerCommunicate(formDataAddDTO);
                response = new XbbResponse<>(formDataAddVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/finishCommunicatePlan", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String finishCommunicatePlan(@RequestBody @Valid FinishPlanDTO finishPlanDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                BaseVO baseVO = saasDetailTabService.finishCommunicatePlan(finishPlanDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/detailCommunicate/list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String customerCommunicateList(@RequestBody @Valid DetailCommunicateDTO detailCommunicateDTO, BindingResult br) {
        XbbResponse<DetailCommunicateVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(SaasMarkEnum.SAAS.getCode(), detailCommunicateDTO.getParentBusinessType(), null, detailCommunicateDTO.getDistributorMark());
                DetailCommunicateVO detailCommunicateVO = saasDetailTabService.customerCommunicateList(detailCommunicateDTO);
                response = new XbbResponse<>(detailCommunicateVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/detailCommunicate/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String detailCommunicateGet(@RequestBody @Valid DetailCommunicateDTO detailCommunicateDTO, BindingResult br) {
        XbbResponse<FormDataAddGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                FormDataAddGetVO formDataAddGetVO = saasDetailTabService.detailCommunicateGet(detailCommunicateDTO);
                response = new XbbResponse<>(formDataAddGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/detailCommunicate/getOther", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String detailCommunicateGetOther(@RequestBody @Valid FormDataGetDTO formDataGetDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(formDataGetDTO.getSaasMark(), formDataGetDTO.getBusinessType(), formDataGetDTO.getMenuId(), formDataGetDTO.getDistributorMark());
                BaseVO baseVO = saasDetailTabService.detailCommunicateGetOther(formDataGetDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 合同退货退款tab
     *
     * @param detailTabDataGetDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/refund/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getRefund(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getRefund(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 退货退款关联作废发票tab
     *
     * @param detailTabDataGetDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/refund/invoice/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getRefundInvoice(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getRefundInvoice(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 初始化全景图，包含：code、name、unit、穿透详情页对应的tab
     * @param panoramaInitDto 入参
     * @param br 校验信息
     * @return java.lang.String
     * @author zcp
     * @date 2019/5/31 11:17
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/panorama/init", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String panoramaInit(@RequestBody @Valid PanoramaInitDTO panoramaInitDto, BindingResult br) {
        XbbResponse<PanoramaInitVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                PanoramaInitVO panoramaInitVo = saasDetailTabService.panoramaInit(panoramaInitDto);
                response = new XbbResponse<>(panoramaInitVo);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }


    /**
     * 客户动态列表
     * @param customerDynamicListDTO 入参
     * @param br 校验结果
     * @return String
     */
    @RequestMapping(value = "/getCustomerDynamicsList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getCustomerDynamicsList(@RequestBody @Valid CustomerDynamicListDTO customerDynamicListDTO, BindingResult br) {
        XbbResponse<CommunicateDynamicsListVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                CommunicateDynamicsListVO communicateDynamicsListVO = saasDetailTabService.getCustomerDynamicsList(customerDynamicListDTO);
                response = new XbbResponse<>(communicateDynamicsListVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 动态列表
     * @param dynamicListDTO 入参
     * @param br 校验结果
     * @return String
     */
    @RequestMapping(value = "/getDynamicsList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getDynamicsList(@RequestBody @Valid DynamicListDTO dynamicListDTO, BindingResult br) {
        XbbResponse<CommunicateDynamicsListVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                CommunicateDynamicsListVO communicateDynamicsListVO = saasDetailTabService.getDynamicsList(dynamicListDTO);
                response = new XbbResponse<>(communicateDynamicsListVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }




    /**
     * 获取tab顺序
     *
     * @param detailTabSettingGetDTO 入参
     * @param br 校验结果
     * @return String
     */
    @RequestMapping(value = "/detailTabSet/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getDetailTabSet(@RequestBody @Valid DetailTabSettingGetDTO detailTabSettingGetDTO, BindingResult br) {
        XbbResponse<DetailTabSettingGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabSettingGetVO detailTabSettingGetVO = saasDetailTabService.getDetailTabSet(detailTabSettingGetDTO);
                response = new XbbResponse<>(detailTabSettingGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 获取tab顺序
     *
     * @param detailTabSettingSaveDTO 入参
     * @param br 校验结果
     * @return String
     */
    @RequestMapping(value = "/saveDetailTabSet", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String saveDetailTabSet(@RequestBody @Valid DetailTabSettingSaveDTO detailTabSettingSaveDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                BaseVO baseVO = saasDetailTabService.saveDetailTabSet(detailTabSettingSaveDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 仓库详情的期初库存tab页
     *
     * @param
     * @param br 校验结果
     * @return String
     */
    @RequestMapping(value = "/getOriStock", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getOriStock(@RequestBody @Valid CabinetFileListGetDTO cabinetFileListGetDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                BaseVO baseVO = saasDetailTabService.getOriStock(cabinetFileListGetDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }


    /**
     * 获取创建人和协同人、负责人(判断高级规则用)
     * @param printDataVisibleDTO
     * @param br
     * @author xingxing.xiao
     * @date 2019/10/14 16:31
     */
    @RequestMapping(value = "/ownerIdAndCoUserIdToPrint/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getOwnerIdAndCoUserIdToPrint(@RequestBody @Valid PrintDataVisibleDTO printDataVisibleDTO, BindingResult br) {
        XbbResponse<HandlerExplainDTO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                HandlerExplainDTO handlerExplainDTO = saasDetailTabService.getOwnerIdAndCoUserIdToPrint(printDataVisibleDTO);
                response = new XbbResponse<>(handlerExplainDTO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }


    @RequestMapping(value = "/changeDocumentStatus", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String changeDocumentStatus(@RequestBody @Valid ChangeDocumentStatusSaveDTO changeDocumentStatusSaveDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ChangeDocumentStatusSaveVO changeDocumentStatusSaveVO = saasDetailTabService.changeDocumentStatus(changeDocumentStatusSaveDTO);
                response = new XbbResponse<>(changeDocumentStatusSaveVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/payment/summary/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getPaymentSummary(@RequestBody @Valid ManagementSummaryDTO managementSummaryDTO, BindingResult br) {
        XbbResponse<ManagementSummaryVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ManagementSummaryVO managementSummaryVO = saasDetailTabService.getPaymentSummary(managementSummaryDTO);
                response = new XbbResponse<>(managementSummaryVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 客户/合同获取付款单列表
     * @param detailTabDataGetDTO
     * @param br
     * @return
     */

	@RequestMapping(value = "/management/paymentSheet/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	public String getPaymentSheetOnManagement(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
		XbbResponse<DetailTabGetVO> response;
		if (br.hasErrors()) {
			String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
			response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
		} else {
			try {
                TransmittableThreadLocalUtil.setValue(detailTabDataGetDTO.getSaasMark(), detailTabDataGetDTO.getBusinessType(), 0L, detailTabDataGetDTO.getDistributorMark());
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getPaymentSheetOnManagement(detailTabDataGetDTO);
				response = new XbbResponse<>(detailTabGetVO);
			} catch (XbbException e) {
				response = new XbbResponse<>(e);
			}
		}
		return JSON.toJSONString(response);
	}

    /**
     * 获取退货退款中的关联红冲回款单列表
     * @param detailTabDataGetDTO 入参
     * @param br 校验
     * @return 回参
     * @author zhouwq
     * @date 2019/12/2 18:50
     */
    @RequestMapping(value = "/refund/redPaymentSheet/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getRefundRedPaymentSheet(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getRefundRedPaymentSheet(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 获取退货退款中的关联红冲应收款列表
     * @param detailTabDataGetDTO 入参
     * @param br 校验
     * @return java.lang.String
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/refund/redPayment/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getRefundRedPayment(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getRefundRedPayment(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 供应商详情页删除供货产品
     *
     * @param supplierProductDelDTO 入参
     * @param br 参数绑定校验
     * @return 回参
     * @author jiantao.xiong
     * @date 2020/4/28
     */
    @RequestMapping(value = "/supplierProduct/delete", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String delSupplierProduct(@RequestBody @Valid SupplierProductDelDTO supplierProductDelDTO, BindingResult br){
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.delSupplierProduct(supplierProductDelDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }

        return JSON.toJSONString(response);
    }

    /**
     * 供应商详情页添加供货产品
     *
     * @param supplierProductAddDTO 入参
     * @param br 校验
     * @return 回参
     * @author jiantao.xiong
     * @date 2020/4/28
     */
    @RequestMapping(value = "/supplierProduct/add", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String addSupplierProduct(@RequestBody @Valid SupplierProductAddDTO supplierProductAddDTO, BindingResult br){
        XbbResponse<FormDataUpdateVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                FormDataUpdateVO formDataUpdateVO = saasDetailTabService.addSupplierProduct(supplierProductAddDTO);
                response = new XbbResponse<>(formDataUpdateVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }

        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/supplierProduct/getLinkProductField", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getLinkProductField(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br){
        XbbResponse<SupplierProductVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                SupplierProductVO supplierProductVO = saasDetailTabService.getLinkProductField(detailTabDataGetDTO);
                response = new XbbResponse<>(supplierProductVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }

        return JSON.toJSONString(response);
    }



    @RequestMapping(value = "/detailExpense/list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String detailExpenseList(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.detailExpenseList(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 详情页汇总关联产品信息
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author long.rao
     * @date 2019-08-28 10:16
     **/
    @RequestMapping(value = "/expenseList/summary", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String summaryExpenseList(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<ExpenseSummaryVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ExpenseSummaryVO productSummaryVO = businessExpenseService.summaryExpenseList(detailTabDataGetDTO);
                response = new XbbResponse<>(productSummaryVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 获取采购退货单中的关联红冲回款单列表
     * @param detailTabDataGetDTO 入参
     * @param br 校验
     * @return 回参
     * @author zhouwq
     * @date 2020/02/24 09:28
     */
    @PostMapping(value = "/returned/redPaySheet/get", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getReturnedRedPaySheet(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getReturnedRedPaySheet(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/returned/invoice/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getReturnedPurchaseInvoice(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getReturnedPurchaseInvoice(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 活动成效
     * @param marketActivityEffectGetDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/marketActivityEffect/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getMarketActivityEffect(@RequestBody @Valid MarketActivityEffectGetDTO marketActivityEffectGetDTO, BindingResult br) {
        XbbResponse<MarketActivityEffectGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.CLUE.getCode(),null, marketActivityEffectGetDTO.getDistributorMark());
                MarketActivityEffectGetVO marketActivityEffectGetVO = marketActivityEffectService.getMarketActivityEffect(marketActivityEffectGetDTO);
                response = new XbbResponse<>(marketActivityEffectGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }



    /**
     市场活动详情页
     * @param
     * @param br
     * @return
     */
    @RequestMapping(value = "/relationSaleClueList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String relationSaleClueList(@RequestBody @Valid RelationSaleClueListDTO relationSaleClueListDTO, BindingResult br) {
        XbbResponse<RelationSaleClueListVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.CLUE.getCode(),null, relationSaleClueListDTO.getDistributorMark());
                RelationSaleClueListVO webRelationSaleClueList = saasDetailTabService.getWebRelationSaleClueList(relationSaleClueListDTO);
                response = new XbbResponse<>(webRelationSaleClueList);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }



    /**
     市场活动详情页 筛选条件
     * @param detailTabConditionListDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/marketActivityClue/listTabCondition", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String listTabCondition(@RequestBody @Valid DetailTabConditionListDTO detailTabConditionListDTO, BindingResult br) {
        XbbResponse<ScreenListVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ScreenListVO screenListVO = saasDetailTabService.listTabCondition(detailTabConditionListDTO);
                response = new XbbResponse<>(screenListVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * @param changeClueStatusDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/clue/invalid", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String clueInvalid(@RequestBody @Valid ChangeClueStatusDTO changeClueStatusDTO, BindingResult br) {
        XbbResponse<ChangeClueStatusVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ChangeClueStatusVO changeClueStatusVO = clueService.invalidClue(changeClueStatusDTO);
                response = new XbbResponse<>(changeClueStatusVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * @param changeClueStatusDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/clue/follow", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String clueFollow(@RequestBody @Valid ChangeClueStatusDTO changeClueStatusDTO, BindingResult br) {
        XbbResponse<ChangeClueStatusVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ChangeClueStatusVO changeClueStatusVO = clueService.followClue(changeClueStatusDTO);
                response = new XbbResponse<>(changeClueStatusVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 回款计划tab的统一入口
     *
     * @param detailTabDataGetDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/paymentTask/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getPaymentTask(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getPaymentTask(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 固定额度记录
     * @param detailTabDataGetDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/creditFixedLimit/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getCreditFixedLimit(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getCreditFixedLimit(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/creditTemporaryLimit/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getCreditTemporaryLimit(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getCreditTemporaryLimit(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/creditCardBill/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getCreditCardBill(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getCreditCardBill(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 关联新建之前需要做的一些事情
     *
     * @param linkAddBeforeDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/linkAdd/before", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String linkAddBefore(@RequestBody @Valid LinkAddBeforeDTO linkAddBeforeDTO, BindingResult br) {
        XbbResponse<DetailTabLinkAddBeforeVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(linkAddBeforeDTO.getSaasMark(), linkAddBeforeDTO.getLinkBusinessType(), null, linkAddBeforeDTO.getDistributorMark());
                DetailTabLinkAddBeforeVO detailTabLinkAddBeforeVO = saasDetailTabService.linkAddBefore(linkAddBeforeDTO);
                response = new XbbResponse<>(detailTabLinkAddBeforeVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 获取营销活动适用对象
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author jyh
     * @since v1.0
     **/
    @RequestMapping(value = "/marketing/applicableObjects", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String marketingApplicableObjects(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.marketingApplicableObjects(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }


    /**
     * 获取营销活动不适用商品
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author jyh
     * @since v1.0
     **/
    @RequestMapping(value = "/marketing/inapplicableGoods", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String marketingInapplicableGoods(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.marketingInapplicableGoods(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 获取核销记录
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author jyh
     * @since v1.0
     **/
    @RequestMapping(value = "/writeOffRecord", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getWriteOffRecord(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getWriteOffRecord(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }


    /**
     * 经销商档案账号管理tab页
     * @param detailTabDataGetDTO
     * @param br
     * @return java.lang.String
     * @throws XbbException
     * @author xinpeng.jiang
     * @date 2021/1/7 15:21
     * @version 1.0
     */
    @RequestMapping(value = "/distributor/account/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getDistributorAccount(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getDistributorAccount(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 普通发货
     * @param outstockShippingDTO
     * @param br
     * @return java.lang.String
     * @throws XbbException
     * @author lee
     * @date 2021/1/7 15:21
     * @version 1.0
     */
    @RequestMapping(value = "/normalShipping/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getNormalShipping(@RequestBody @Valid OutstockShippingDTO outstockShippingDTO, BindingResult br) {
        XbbResponse<OutstockShippingVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                OutstockShippingVO outstockShippingVO = saasDetailTabService.normalShipping(outstockShippingDTO);
                response = new XbbResponse<>(outstockShippingVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 电子面单发货
     * @param outstockShippingDTO
     * @param br
     * @return java.lang.String
     * @throws XbbException
     * @author lee
     * @date 2021/1/7 15:21
     * @version 1.0
     */
    @RequestMapping(value = "/electronicShipping/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getElectronicShipping(@RequestBody @Valid OutstockShippingDTO outstockShippingDTO, BindingResult br) {
        XbbResponse<OutstockShippingVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                OutstockShippingVO outstockShippingVO = saasDetailTabService.electronicShipping(outstockShippingDTO);
                response = new XbbResponse<>(outstockShippingVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 普通发货保存
     * @param outstockShippingDTO
     * @param br
     * @return java.lang.String
     * @throws XbbException
     * @author lee
     * @date 2021/1/7 15:21
     * @version 1.0
     */
    @RequestMapping(value = "/normalShipping/save", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String saveNormalShipping(@RequestBody @Valid OutstockShippingDTO outstockShippingDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                BaseVO baseVO = saasDetailTabService.saveNormalShipping(outstockShippingDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 电子面单发货保存
     * @param outstockShippingDTO
     * @param br
     * @return java.lang.String
     * @throws XbbException
     * @author lee
     * @date 2021/1/7 15:21
     * @version 1.0
     */
    @RequestMapping(value = "/electronicShipping/save", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String saveElectronicShipping(@RequestBody @Valid OutstockShippingDTO outstockShippingDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                BaseVO baseVO = saasDetailTabService.saveElectronicShipping(outstockShippingDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 电子面单复打
     * @param outstockShippingDTO
     * @param br
     * @return java.lang.String
     * @throws XbbException
     * @author lee
     * @date 2021/1/7 15:21
     * @version 1.0
     */
    @RequestMapping(value = "/electronicShipping/copy", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String copyElectronicShipping(@RequestBody @Valid OutstockShippingDTO outstockShippingDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                BaseVO baseVO = saasDetailTabService.copyElectronicShipping(outstockShippingDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 获取物流信息
     * @param outstockShippingDTO
     * @param br
     * @return java.lang.String
     * @throws XbbException
     * @author lee
     * @date 2021/1/7 15:21
     * @version 1.0
     */
    @RequestMapping(value = "/expressInfo/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getExpressInfo(@RequestBody @Valid OutstockShippingDTO outstockShippingDTO, BindingResult br) {
        XbbResponse<OutstockShippingVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                OutstockShippingVO outstockShippingVO = saasDetailTabService.getExpressInfo(outstockShippingDTO);
                response = new XbbResponse<>(outstockShippingVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * @Author: wujian
     * @Description: 取消发货接口
     * @Date: 上午9:51 2021/2/2
     * @Param: [outstockShippingDTO, br]
     * @return: java.lang.String
     **/
    @RequestMapping(value = "/delivery/update", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String updateExpress(@RequestBody @Valid OutstockShippingDTO outstockShippingDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                BaseVO baseVO = saasDetailTabService.cancelDelivery(outstockShippingDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     *
     * @Description: 获取审批记录
     * @param approvalRecordsDTO
     * @param br
     * @return: java.lang.String
     * @Author: shen.yang
     * @Date: 2022/6/14  17:24
     */
    @RequestMapping(value = "/approve/records", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String approveRecords(@RequestBody @Valid ApprovalRecordsDTO approvalRecordsDTO, BindingResult br) {
        XbbResponse<ApprovalRecordsVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ApprovalRecordsVO approvalRecordsVO = saasDetailTabService.getApprovalRecords(approvalRecordsDTO);
                response = new XbbResponse<>(approvalRecordsVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }






}
